home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / misc / sci / RARS_Amiga_3.lha / RARS / indretti.cpp < prev    next >
Encoding:
Text File  |  1995-05-27  |  54.9 KB  |  1,302 lines

  1. // INDRETTI.CPP - A robot "driver" for RARS, by M. Inman, March 1995
  2. // written for ver. 0.39 of RARS
  3.  
  4. ///////////////////////////////////////////////////////////////////////
  5. ///////////////////////////////////////////////////////////////////////
  6. ///////////////////////////////////////////////////////////////////////
  7.  
  8. // This is the track setup information (Data file to be read at run-time)
  9.  
  10. //TSI:! Speed2.trk
  11. //TSI:
  12. //TSI:CourseNSeg    = 18
  13. //TSI:CourseWidth   = 150.0
  14. //TSI:CourseRadii   =             0             300               0             450               0             550               0             480               0             350               0            -200               0             350               0            -200               0             710 
  15. //TSI:CourseLengths =          2770            1.65             450             .55             600             .48          3350.0            2.10             300              .5             300              .5             300              .5             300              .5           400.0            1.54 
  16. //TSI:
  17. //TSI:CornerSpeed =     6.329393951     5.912184787     7.258597876     8.503967327     8.841662702     7.480799852     5.832880753     5.774993855    12.695238414     7.136596854    13.763743118     6.202806072    12.958238301     7.199428595    13.207036476     6.212034935     5.120371962     5.829358225
  18. //TSI:SteerGain   =     1.031690515     0.779369698     1.080470164     0.895366396     0.830030990     0.989639183     0.971582806     0.953855875     0.906739134     0.898825729     1.170021835     0.973322322     0.872898064     0.961963175     0.924148526     0.859151217     0.951598482     1.030468993
  19. //TSI:SteerDamp   =     1.650265225     1.989676192     1.612945259     1.507956567     1.666767877     1.382440558     1.465342753     1.832998034     1.822962284     1.634381182     1.645862509     1.929993865     1.450396257     1.753377870     1.586793485     1.647315881     1.966455698     1.525302186
  20. //TSI:SteerBias   =     9.224241718     8.676539506     9.346831208    11.923922492    10.507811225     9.498229096    12.635159306    10.306748299    11.495980023     9.248916750     9.901591347     9.426495951    10.712544922     9.988766542     9.786034935     9.409648976     9.717768804     9.437670153
  21. //TSI:ExtraSpace  =    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000
  22. //TSI:CornerSetup =     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000
  23. //TSI:BrakeFactor =     0.000345057     0.000416025     0.000402947     0.000381282     0.000416151     0.000454610     0.000369081     0.000383844     0.000373214     0.000448772     0.000369957     0.000387683     0.000486691     0.000337756     0.000392489     0.000403302     0.000372547     0.000408188
  24. //TSI:AccelFactor =     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000
  25. //TSI:STEFactor   =     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000     3.600000000
  26. //TSI:STEFactor2  =     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000     2.200000000
  27. //TSI:
  28. //TSI:TweakMode     = Segment
  29. //TSI:TweakNLaps    = 100
  30. //TSI:TweakSStep    = 0.01
  31. //TSI:TweakEStep    = 0.002
  32. //TSI:SegmentList   =             0               1               2               3               4               5               6               7               8               9              10              11              12              13              14              15              16              17
  33. //TSI:ParameterList = CornerSpeed BrakeFactor SteerGain SteerDamp SteerBias
  34. //TSI:
  35. //TSI:/*
  36. //TSI:
  37. //TSI:! Stef2.trk
  38. //TSI:
  39. //TSI:CourseNSeg    = 16
  40. //TSI:CourseWidth   = 90.0
  41. //TSI:CourseRadii   =   0 120   0 200   0 300     -200  0 110   0 120 -120   0 -50  0 125
  42. //TSI:CourseLengths = 770  .9 200 .25 200 3.0 2.094395 90 2.9 150  .7   .7 140 1.9 70 3.2
  43. //TSI:
  44. //TSI:CornerSpeed =    12.593450307     5.928000000     7.341919180     6.460516332     5.467798452     6.274155284     5.650403828     6.283490304     5.860587239    15.004681077    10.060070422     5.700000000     5.579386176     7.500811142     5.750183712     6.165120000
  45. //TSI:SteerGain   =     0.790902461     0.933390011     0.782144587     0.846714613     0.847974400     0.899891200     1.052427494     0.972169908     0.846714613     0.881893376     0.865280000     0.832000000     0.815113761     0.881893376     0.832000000     0.775084412
  46. //TSI:SteerDamp   =     1.481750574     1.466636718     1.175774116     1.481750573     1.414000000     1.621096404     1.439442480     1.382440558     1.718310313     1.352779011     1.470560000     1.455560288     1.410653630     1.414000000     1.529382400     1.441148800
  47. //TSI:SteerBias   =     8.903731200     8.525754436     8.879977083     9.053206712     9.615968520     9.515011240     8.736000000     9.341405917     8.890503440     9.173523159     8.222253312     9.085440000     8.736000000     8.725656576     9.085440000     9.085440000
  48. //TSI:ExtraSpace  =    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000
  49. //TSI:CornerSetup =     0.935000000     0.865280000     0.800000000     0.831014912     0.800000000     0.840000000     0.800000000     0.700000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000
  50. //TSI:BrakeFactor =     0.000384639     0.000403902     0.000373656     0.000373656     0.000342046     0.000412270     0.000380831     0.000349440     0.000408188     0.000355727     0.000396413     0.000336000     0.000352517     0.000349440     0.000349026     0.000349440
  51. //TSI:AccelFactor =     0.000800000     0.000800000     0.000832000     0.000832000     0.000814395     0.000799053     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000
  52. //TSI:STEFactor   =     3.000000000     3.000000000     3.120000000     3.055753488     2.877788659     3.120000000     3.116305920     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000
  53. //TSI:STEFactor2  =     1.560000000     1.687296000     1.622400000     1.560000000     1.560000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000
  54. //TSI:
  55. //TSI:TweakMode     = Segment
  56. //TSI:TweakNLaps    = 25
  57. //TSI:TweakSStep    = 0.04
  58. //TSI:TweakEStep    = 0.009
  59. //TSI:SegmentList   =         0               1              2                3               4               5                                                   8           9                10            11               12              13              14              15
  60. //TSI:ParameterList = CornerSpeed BrakeFactor SteerBias SteerGain SteerDamp
  61. //TSI:
  62. //TSI:/*
  63. //TSI:
  64. //TSI:! ANew.trk
  65. //TSI:
  66. //TSI:CourseNSeg    = 23
  67. //TSI:CourseWidth   = 120.0
  68. //TSI:CourseRadii   =    0      300   0     -200   0      400     -250      350   0       750    0      250   0      280   0    -200   -1100     -150   0     -450     -650   0      390 
  69. //TSI:CourseLengths = 2455 1.919862 300 0.698132 400 0.698132 0.698132 1.570796 700  0.349066 1700 1.570796 900 3.141593 550 1.37881 0.78539 0.872665 400 0.785398 0.977384 640 3.211406
  70. //TSI:
  71. //TSI:CornerSpeed =     6.134120742     6.329393951     8.341443045     6.165120000     8.672480887     9.298291679     7.635775241     6.922527495     5.928000000     5.693251200     5.809440000     6.041817600     5.700000000     6.534829916     5.579386176     5.809440000     7.212318405     5.700000000     5.985471841     6.283490304     6.102235776     5.358442483     5.928000000
  72. //TSI:SteerGain   =     0.934496455     0.799052800     0.935886848     0.832000000     0.906465299     0.935604210     0.881627044     1.052745423     0.847974400     0.800000000     0.865018685     0.823513600     0.782835256     0.800000000     0.800000000     0.832000000     0.800000000     0.807043328     0.800000000     0.847974400     0.807043328     0.944960252     0.832000000
  73. //TSI:SteerDamp   =     1.455560288     1.455560288     1.470560000     1.481750573     1.455560288     1.437303983     1.441148800     1.426449082     1.384079308     1.470560000     1.513782700     1.470560000     1.455120709     1.414000000     1.470560000     1.440713573     1.498794752     1.470560000     1.414000000     1.412325824     1.441148800     1.441148800     1.414000000
  74. //TSI:SteerBias   =     9.630275666     8.057808246     8.212518164     8.982121074     9.071942285     8.903731200     8.390054400     8.558694493     9.085440000     8.400000000     9.448857600     9.074682839     8.551143444     8.733361728     8.736000000     8.304475845     9.085440000     8.736000000     8.473954944     8.736000000     8.820695345     8.736000000     8.400000000
  75. //TSI:ExtraSpace  =    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000
  76. //TSI:CornerSetup =     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000
  77. //TSI:BrakeFactor =     0.000328890     0.000335501     0.000335602     0.000342451     0.000359711     0.000348921     0.000396413     0.000336000     0.000349440     0.000336000     0.000332179     0.000342046     0.000336000     0.000342348     0.000400619     0.000389063     0.000363308     0.000336000     0.000335501     0.000352517     0.000349334     0.000349229     0.000335205
  78. //TSI:AccelFactor =     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000
  79. //TSI:STEFactor   =     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000
  80. //TSI:STEFactor2  =     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000
  81. //TSI:
  82. //TSI:TweakMode     = Segment
  83. //TSI:TweakNLaps    = 25
  84. //TSI:TweakSStep    = 0.04
  85. //TSI:TweakEStep    = 0.009
  86. //TSI:SegmentList   = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
  87. //TSI:ParameterList = CornerSpeed BrakeFactor SteerBias SteerGain SteerDamp
  88. //TSI:
  89. //TSI:/*
  90. //TSI:
  91. //TSI:! V03.TRK
  92. //TSI:
  93. //TSI:
  94. //TSI:CourseNSeg    = 10
  95. //TSI:CourseWidth   = 110.0
  96. //TSI:CourseRadii   =             0         226.436           -1400         226.436               0          163.22        -216.092         201.149               0         352.874
  97. //TSI:CourseLengths =        1310.0             2.9             .95        2.107129          561.37             1.0             1.3            2.07           252.5             .54
  98. //TSI:
  99. //TSI:CornerSpeed =     5.785333367     6.885801458     6.004320785     6.338811158    11.500000000     9.942664482     7.397962955     5.679777562     7.800843587     7.212318405
  100. //TSI:SteerGain   =     0.898825729     0.819372835     0.943556379     1.011056705     0.800000000     0.852405175     1.019958210     1.137961810     0.831014912     0.914722211
  101. //TSI:SteerDamp   =     1.896453505     1.632939223     1.527571611     1.523956463     1.414000000     1.392539891     1.521692409     1.494796142     1.498794752     1.620117409
  102. //TSI:SteerBias   =     9.330345692    11.004633998    10.690421140    11.819858566     8.400000000     8.866784612     8.893189182    10.204701286     9.826811904     9.151813116
  103. //TSI:ExtraSpace  =    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000
  104. //TSI:CornerSetup =     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000
  105. //TSI:BrakeFactor =     0.000341641     0.000436993     0.000355199     0.000368969     0.000336000     0.000376946     0.000440840     0.000344953     0.000362448     0.000473355
  106. //TSI:AccelFactor =     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000
  107. //TSI:STEFactor   =     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000
  108. //TSI:STEFactor2  =     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000
  109. //TSI:
  110. //TSI:SegmentList   =             0               1               2               3                               5               6               7               8               9
  111. //TSI:TweakMode     = Segment
  112. //TSI:TweakNLaps    = 10
  113. //TSI:TweakSStep    = 0.04
  114. //TSI:TweakEStep    = 0.009
  115. //TSI:ParameterList = CornerSpeed BrakeFactor SteerBias SteerGain SteerDamp
  116. //TSI:
  117. //TSI:/*
  118. //TSI:
  119. //TSI:! Oval2.trk
  120. //TSI:
  121. //TSI:
  122. //TSI:CourseNSeg    = 4
  123. //TSI:CourseWidth   = 100.0
  124. //TSI:CourseRadii   =             0             400               0             400
  125. //TSI:CourseLengths =           600       3.1415927             600       3.1415927
  126. //TSI:
  127. //TSI:CornerSpeed =     5.000000000     6.800000000     5.000000000     6.800000000
  128. //TSI:SteerGain   =     0.950000000     1.300000000     0.950000000     1.300000000
  129. //TSI:SteerDamp   =     2.000000000     1.250000000     2.000000000     1.250000000
  130. //TSI:SteerBias   =     9.000000000    25.000000000     9.000000000    25.000000000
  131. //TSI:ExtraSpace  =    10.000000000    10.000000000    10.000000000    10.000000000
  132. //TSI:CornerSetup =     0.800000000     0.800000000     0.800000000     0.800000000
  133. //TSI:BrakeFactor =     0.000390000     0.000500000     0.000390000     0.000500000
  134. //TSI:AccelFactor =     0.001000000     0.001000000     0.001000000     0.001000000
  135. //TSI:STEFactor   =     3.610000000     3.610000000     3.610000000     3.610000000
  136. //TSI:STEFactor2  =     2.200000000     2.200000000     2.200000000     2.200000000
  137. //TSI:
  138. //TSI:SegmentList   =             0               1               2               3  
  139. //TSI:TweakMode     = Segment
  140. //TSI:TweakNLaps    = 50
  141. //TSI:TweakSStep    = 0.04
  142. //TSI:TweakEStep    = 0.009
  143. //TSI:ParameterList = BrakeFactor AccelFactor STEFactor STEFactor2 CornerSpeed
  144. //TSI:
  145. //TSI:/*
  146. //TSI:
  147. //TSI:! ZandVort.trk
  148. //TSI:
  149. //TSI:CourseNSeg    = 30
  150. //TSI:CourseWidth   = 131.25
  151. //TSI:CourseRadii   =      0 1312.34      0 426.51     0 -164.04     0 264.0      0 656.17      0 328.08      0 -492.13      0 492.13      0 574.15      0 -492.13      0 656.17      0 -65.62      0 246.06      0 -131.23     0  215.0
  152. //TSI:CourseLengths = 2484.0     .44 492.13   1.57 710.0    1.22 98.43  1.44 656.17    .61 721.78    .79 328.08     .79 557.74   2.27 557.74    .44 131.23     .52 492.13    .35 328.08   3.14 164.04   1.31 328.08      .4 264.0 3.1416
  153. //TSI:        
  154. //TSI:CornerSpeed =     5.980191060     5.980191060     6.532856398     6.411724800     6.165120000     6.668193792     5.579386176     6.600178215     6.409788459     6.344408617     8.103271684     6.102235776     5.700000000     6.534829916     5.693251200     5.809440000     6.592363604     5.809440000  
  155. //TSI:SteerGain   =     0.814148667     0.899619433     0.832000000     0.865280000     0.815360000     0.823264899     0.800000000     0.823264899     0.856454144     0.799052800     0.865018685     0.800000000     0.815360000     0.799052800     0.908615627     0.783071744     0.832000000     0.832000000  
  156. //TSI:SteerDamp   =     1.384079308     1.513325537     1.529382400     1.497020179     1.605978121     1.455560288     1.384079308     1.468818857     1.483507046     1.470115891     1.441148800     1.414000000     1.412325824     1.483507046     1.414000000     1.414000000     1.498794752     1.455560288  
  157. //TSI:SteerBias   =     8.400000000     8.893189182     8.380120576     8.400000000     8.400000000     8.304475845     8.400000000     8.561280000     8.390054400     8.400000000     8.736000000     8.400000000     8.646892800     8.400000000     9.630275666     8.057808246     8.400000000     9.257083964  
  158. //TSI:ExtraSpace  =    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000    10.000000000  
  159. //TSI:CornerSetup =     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000     0.800000000  
  160. //TSI:BrakeFactor =     0.000352517     0.000366617     0.000349440     0.000363418     0.000335501     0.000336000     0.000359285     0.000338958     0.000336000     0.000338958     0.000336000     0.000362987     0.000336000     0.000335205     0.000335602     0.000362987     0.000336000     0.000336000  
  161. //TSI:AccelFactor =     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000     0.000800000  
  162. //TSI:STEFactor   =     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000     3.000000000  
  163. //TSI:STEFactor2  =     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000     1.500000000  
  164. //TSI:
  165. //TSI:TweakMode     = Segment
  166. //TSI:TweakNLaps    = 25
  167. //TSI:TweakSStep    = 0.04
  168. //TSI:TweakEStep    = 0.009
  169. //TSI:SegmentList   = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
  170. //TSI:ParameterList = BrakeFactor CornerSpeed STEFactor STEFactor2 
  171. //TSI:
  172. //TSI:/*
  173.  
  174.  
  175. ///////////////////////////////////////////////////////////////////////
  176. ///////////////////////////////////////////////////////////////////////
  177. ///////////////////////////////////////////////////////////////////////
  178.  
  179. // Used to be the file config.h
  180.  
  181. #ifndef CONFIG_H
  182. #define CONFIG_H 1
  183.  
  184. #include <dos.h>
  185. #include <stdlib.h>
  186. #include <string.h>
  187. #include <stdio.h>
  188. #include <ctype.h>
  189.  
  190.  
  191. //
  192. // A single item in an array that describes possible items in a configuration
  193. // file.
  194. //
  195. typedef struct _config_template
  196. { char   *name;       // Name to search config file for.      
  197.   short   count;      // Count of parameters to match.        
  198.   char    size;       // sizeof() each item, applies to arrays (count > 1)
  199.   char    allocate;   // boolean - 1 indicates need to malloc space for string.
  200.   char   *in_format;  // scanf()  format string for parameters.
  201.   void   *params;     // Pointer to parameters for storage.  
  202. } CONFIG_TEMPLATE;
  203.  
  204.  
  205. //
  206. // Just a number and an associated text string
  207. // Used to evaluate text strings to the appropriate numbers.
  208. //
  209. typedef struct _ttn
  210. {  int  N;
  211.   char *text;
  212. } ttn_t;
  213.  
  214.  
  215.  int   ReadConfigFilePiece( FILE *fp, CONFIG_TEMPLATE list[] , ttn_t *ttn );
  216. void   InterpretConfigFileLine( char *buf, CONFIG_TEMPLATE list[] , ttn_t *ttn );
  217. void   InterpretConfigFileParameters( char *cp, CONFIG_TEMPLATE *tp , ttn_t *ttn );
  218.  int   text_to_number( char *text , ttn_t *ttn );
  219. char  *number_to_text( int n , ttn_t *ttn );
  220.  int   str_cmptrim(const char *string1, const char *string2);
  221. char **array_of_words( char *string );
  222. char  *line_starts_with( char *line, char *tag );
  223.  
  224. #endif
  225.  
  226.  
  227. ///////////////////////////////////////////////////////////////////////
  228. ///////////////////////////////////////////////////////////////////////
  229. ///////////////////////////////////////////////////////////////////////
  230.  
  231. // Used to be the file config.cpp
  232.  
  233. // config.cpp - A fairly generic configuration file reader
  234. // Ported into RARS by Mike Inman, April 1995
  235.  
  236. // #include "config.h"
  237.  
  238. //
  239. // Entry point for piece readers (which read up to a /*, then return)
  240. //
  241. int ReadConfigFilePiece( FILE *fp, CONFIG_TEMPLATE list[] , ttn_t *ttn )
  242. { char  string[1200];
  243.   char *buf = string;
  244.   char *buf2;
  245.   
  246.   while ( fgets( buf, 1199 , fp ) != NULL )
  247.     { buf2 = line_starts_with( buf , "//TSI:" );  // All lines pertaining to Track Setup Info
  248.                                                   // Begin with a //TSI:
  249.       if ( buf2 != NULL )
  250.         { if ( (*buf2 == '/') && (*(buf2+1) == '*' ) )  // found a /*... we're done reading this piece
  251.             return 1;
  252.           InterpretConfigFileLine( buf2 , list , ttn );
  253.         }
  254.     }
  255.  
  256.   return 0;
  257. }
  258.  
  259.  
  260. //
  261. // Takes one line of text from a config file and interprets it according to
  262. // the CONFIG_TEMPLATE.
  263. //
  264. void InterpretConfigFileLine( char *buf, CONFIG_TEMPLATE list[] , ttn_t *ttn )
  265. {
  266.   CONFIG_TEMPLATE *tp;
  267.   char            *cp, *np;
  268.  
  269.  
  270.   np = buf; 
  271.   while ( isspace(*np) && *np != '\0' )
  272.     np++;                                            // skip leading blanks
  273.   if ( *np == '\0' )                                  
  274.     return;                                          // empty line, so return
  275.  
  276.   cp = np;
  277.   while ( *cp != '=' && *cp != '\0' )
  278.     cp++;                                            // get line name until =
  279.   if ( *cp ==  '\0' )                                   
  280.     return;                                          // if no = then return
  281.   *(cp++) = '\0';                                    // np = name;cp = param
  282.   
  283.  
  284.   for ( tp = list; tp->name != NULL; tp++ )          // search in list for name
  285.     { if ( str_cmptrim( tp->name, np ) )             // if name found
  286.         { while ( isspace(*cp) && *cp != '\0' )
  287.             cp++;                                    // skip blanks after =
  288.           if ( *cp != '\0' )                         // if not empty read params
  289.             InterpretConfigFileParameters( cp , tp , ttn );
  290.           return;                                    // either way, this one is done
  291.         }
  292.     }
  293.   return;                                            // name not found
  294. }
  295.  
  296.  
  297. //
  298. // Given a list of parameters and the CONFIG_TEMPLATE entry describing what
  299. // to do with them, do it.
  300. //
  301. void InterpretConfigFileParameters( char *cp, CONFIG_TEMPLATE *tp , ttn_t *ttn )
  302. { void  *temp_p;
  303.   char   string[120]; 
  304.   char **array;
  305.    int  *n_list;
  306.    int   i;
  307.  
  308.   if ( strcmp( tp->in_format , "TN" ) == 0 )   // Is this the special Text to number formatted line?
  309.     { array = array_of_words( cp );
  310.       n_list = (int *)tp->params;              // These are always arrays of integers
  311.       i = 0;
  312.       while ( array[i] != NULL )
  313.         { *n_list = text_to_number( array[i] , ttn );
  314.           n_list++;
  315.           i++;
  316.         }
  317.       n_list++;
  318.       *n_list = -1; // End of list is marked by a -1
  319.       return;
  320.     }
  321.  
  322.   if ( tp->allocate ) // Only applies to strings, allocates memory to contain whatever is on the line (up to 120 characters)
  323.     { sscanf( cp, tp->in_format, string );
  324.       if ( (temp_p = malloc( strlen( string ) + 2 )) == NULL )
  325.         { printf( "Error during malloc(), not enough free memory?\n" );
  326.           exit( 1 );
  327.         }
  328.       memcpy( tp->params , &temp_p , sizeof( temp_p ) ); 
  329.       strcpy( (char *)temp_p , string );
  330.       return;
  331.     }
  332.  
  333.   if ( tp->count == 1 ) // Single item, handle simply
  334.     { sscanf( cp, tp->in_format, tp->params );
  335.       return;
  336.     }
  337.  
  338.   // Read each parameter in succession
  339.   i = 0;
  340.   while (( *cp != '\0' ) && ( i < tp->count ))
  341.     { sscanf( cp, tp->in_format, (void *)((char *)tp->params + (i * tp->size)) );  // Read the first item in line
  342.  
  343.       while ( !isspace(*cp) && *cp != '\0' )     // Read to end of first item
  344.         cp++;                                    
  345.       while ( isspace(*cp) && *cp != '\0' )      // Skip blanks
  346.         cp++;
  347.       i++;                                       // Do the next item in the array
  348.     }
  349. }
  350.  
  351.  
  352. //
  353. // Given a string, attempt to match it to the ttnumber list
  354. //   and return its value.
  355. // If there is no match, return -1.
  356. //
  357. int text_to_number( char *text , ttn_t *ttn )
  358. { int i = 0;
  359.   while (( ttn[i].text != NULL ) && ( ttn[i].N != -1 ))
  360.     { if ( strcmp( text , ttn[i].text ) == 0 )
  361.         return ttn[i].N;
  362.       i++;
  363.     }
  364.   return -1;  // Bad entry constitutes an automatic End of List marker
  365. }
  366.  
  367. //
  368. // Find N in the list and return the corresponding string
  369. // If there is no match, return "".
  370. //
  371. char *number_to_text( int n , ttn_t *ttn )
  372. { int i = 0;
  373.   while (( ttn[i].text != NULL ) && ( ttn[i].N != -1 ))
  374.     { if ( n == ttn[i].N )
  375.         return ttn[i].text;
  376.       i++;
  377.     }
  378.   return ""; 
  379. }
  380.  
  381.  
  382. //
  383. // Some handy custom string manipulation functions
  384. //
  385.  
  386. //
  387. //  Compares string1 with string2 ignoring any leading or        
  388. //  trailing blanks in either string                             
  389. //  Returns 0 : if both strings are different                            
  390. //          1 : if both strings are the same                             
  391. //                                                                      
  392. int  str_cmptrim(const char *string1, const char *string2)
  393. {
  394.   unsigned int i,j,k,l;
  395.  
  396.   int ok;
  397.  
  398.   if( string1 == NULL && string2 == NULL) return 1;
  399.   if( string1 == NULL || string2 == NULL) return 0;
  400.  
  401.   if( string1[0] == '\0' && string2[0] == '\0') return 1;
  402.   if( string1[0] == '\0' || string2[0] == '\0') return 0;
  403.  
  404.   k = l = 0;
  405.   for (i=0; string1[i] != '\0'; i++)
  406.     if ( string1[i] != ' ' && string1[i] != '\t' )
  407.     {
  408.       k = i;
  409.       break;
  410.     }
  411.  
  412.   for (i=0; string2[i] != '\0'; i++)
  413.     if ( string2[i] != ' ' && string2[i] != '\t' )
  414.     {
  415.       l = i;
  416.       break;
  417.     }
  418.  
  419.   for (i=strlen(string1)-1; i > k; i--)
  420.     if ( string1[i] != ' ' && string1[i] != '\t' ) break;
  421.  
  422.   for (j=strlen(string2)-1; j > k; j--)
  423.     if ( string2[j] != ' ' && string2[j] != '\t' ) break;
  424.  
  425.   for(; string1[k] == string2[l] && k < i && l < j; k++,l++);
  426.  
  427.   ok =( ((string1[k] == '\t' || string1[k] == ' ') && (string2[l] == '\t' || string2[l] == ' ')) || (string1[k] == string2[l]) );
  428.  
  429.   return ( (k == i && l == j && ok   )?1:0 );
  430. }
  431.  
  432.  
  433.  
  434. //
  435. // Takes a list of blank separated words and converts it to an array of
  436. // strings where each word is now a null terminated string.  Uses the same
  437. // space that the original list occupied, replacing blanks with nulls.
  438. // The array of pointers is placed after the end of the original string,
  439. // so plenty of extra space should be provided for this.
  440. //
  441. // Considers either a null or /r or /n to be the end of the original list.
  442. //
  443. char **array_of_words( char *string )
  444. {  int   i = 0;
  445.    int   j = 0;
  446.    int   k = 0;
  447.   char **array;
  448.  
  449.   while (( string[i] != '\0' ) &&   // Find the end of the list
  450.          ( string[i] != '\r' ) &&
  451.          ( string[i] != '\n' ))
  452.     i++;
  453.  
  454.   string[i] = ' ';                  // Replace the end of list with a space (so all words will end in a space)
  455.   while ( string[i-1] == ' ' )      // Eliminate consisderation of any trailing blanks 
  456.     i--;
  457.   array = (char **)&(string[i+1]);  // Locate the array after the list
  458.  
  459.   while ( j < i )
  460.     { while ( string[j] == ' ' )
  461.         j++;                        // Skip leading or extra blanks
  462.  
  463.       if ( j < i )
  464.         { array[k++] = (char *)&(string[j]);  // Array element points to first non-blank character
  465.  
  466.           while( string[j] != ' ' )
  467.             j++;                    // Scan to next blank
  468.           string[j] = '\0';         // Convert the blank to a NULL, terminating the array-word-string
  469.           j++;
  470.         }
  471.     }
  472.   array[k] = NULL;                  // NULL indicates the end of the array of words
  473.  
  474.   return array;
  475. }
  476.  
  477. //
  478. // Line Starts With...
  479. // Sees if the line starts with the given string (tag), if it does, 
  480. // returns the part of the line that follows the given string.
  481. // Otherwise, returns NULL, indicating no match.
  482. //
  483. char *line_starts_with( char *line, char *tag )
  484. { int i = 0;
  485.  
  486.   while ( tag[i] != NULL )
  487.     { if ( line[i] != tag[i] )
  488.         return NULL;
  489.       i++;
  490.     }
  491.   return &(line[i]);
  492. }
  493.  
  494.  
  495. ///////////////////////////////////////////////////////////////////////
  496. ///////////////////////////////////////////////////////////////////////
  497. ///////////////////////////////////////////////////////////////////////
  498.  
  499. // The "real" indretti code begins here
  500.  
  501. #include <string.h>
  502. #include <stdlib.h>
  503. #include <math.h>
  504. #include <stdio.h>
  505. #include "track.h"
  506. #include "car.h"
  507.  
  508. #ifdef WATCOM
  509. #include <graph.h>
  510. #endif 
  511.  
  512.  
  513. extern    char *glob_name;       // The name string, below, will be copied here
  514.  
  515. extern segment *trackout;        // global variables that give a description of the track
  516. extern segment *trackin;
  517. extern     int  NSEG;
  518. extern  double  width;
  519.  
  520. static     int  seg = 0;      // Keeps track of what segment car is in, would prefer to
  521.                                  // access this information from the situation, but that is
  522.                                  // not possible for the 4-30-95 races.
  523.  
  524. // Maximum number of track segments
  525. #define MAXSEG          64
  526. // Maximum number of driver parameters
  527. #define NPARM           15
  528.  
  529. //
  530. // These are "default" values that should be good for any track.
  531. //
  532. static double CORNER_FACT        = 5.7;     // The "corner speed constant"
  533. static double STEER_GAIN         = 0.8;     // servo gain, for staying in "lane"
  534. static double STEER_DAMP         = 1.414;   // damping factor to prevent oscillation
  535. static double STEER_BIAS         = 8.4;     // bias factor for steering through corners
  536. static double EXTRA_SPACE        = 10.0;    // how far away from the walls to target the car
  537. static double CORNER_SETUP       = 0.8;     // where to setup on the track for a corner
  538. static double BRAKE_FACT         = 0.000336;// The "braking ability constant"
  539. static double ACCEL_FACT         = 0.0008;  // The "acceleration ability constant"
  540. static double STE_FACT           = 3.0;     // The "see the end of a curve constant"
  541. static double STE_FACT2          = 1.5;     // The other "see the end of a curve constant"
  542.  
  543. // Array pointers, for arrays of the above variables (to specialize them segment by segment)
  544. static double *aCORNER_FACT  ;
  545. static double *aSTEER_GAIN   ;
  546. static double *aSTEER_DAMP   ;
  547. static double *aSTEER_BIAS   ;
  548. static double *aEXTRA_SPACE  ;
  549. static double *aCORNER_SETUP ;
  550. static double *aBRAKE_FACT   ;
  551. static double *aACCEL_FACT   ;
  552. static double *aSTE_FACT     ;
  553. static double *aSTE_FACT2    ;
  554.  
  555. //
  556. // An array of pointers to the arrays of factors
  557. // Just an easier way to get ahold of all the factors with one variable
  558. //
  559. // NOTE: The order of the variables in this array must correspond to the
  560. // numbers and names of the factors in the ttnumber array.
  561. //
  562. // Also note: These "Initalizing values" will be overwritten when space
  563. // is allocated in ConfigureIndretti()
  564. //
  565. static double *factors[] =
  566. {aCORNER_FACT       
  567. ,aSTEER_GAIN        
  568. ,aSTEER_DAMP        
  569. ,aSTEER_BIAS         
  570. ,aEXTRA_SPACE       
  571. ,aCORNER_SETUP      
  572. ,aBRAKE_FACT        
  573. ,aACCEL_FACT        
  574. ,aSTE_FACT          
  575. ,aSTE_FACT2         
  576. , NULL
  577. }; 
  578.  
  579. //
  580. // An array of pointers to the default values for the factors.
  581. // 
  582. // Note: the order of this array must match the order of factors[]
  583. //
  584. static double *def_fact[] =
  585. {&CORNER_FACT       
  586. ,&STEER_GAIN        
  587. ,&STEER_DAMP        
  588. ,&STEER_BIAS         
  589. ,&EXTRA_SPACE       
  590. ,&CORNER_SETUP      
  591. ,&BRAKE_FACT        
  592. ,&ACCEL_FACT        
  593. ,&STE_FACT          
  594. ,&STE_FACT2         
  595. , NULL
  596. }; 
  597.  
  598.  
  599. #define TWEAK_COURSE    99
  600. #define TWEAK_SEGMENTS  98
  601. #define TWEAK_OFF       97
  602.  
  603. //
  604. // More Config file variables
  605. //
  606. static     int  TweakMode  = TWEAK_OFF;      
  607. static     int  TweakNLaps = 25;      
  608. static  double  TweakSStep = 0.04;      
  609. static  double  TweakEStep = 0.009;      
  610. static     int  cNSEG      = 0;          
  611. static  double  cwidth     = 0.0;
  612. static  double *Radii;
  613. static  double *Lengths;
  614. static     int *Segments;
  615. static     int *Parameters;
  616.  
  617. //
  618. // This is a list of Text to number conversions.
  619. // CONFIG_TEMPLATE items that have TN as a format will
  620. // use this list to convert the text that follows them into
  621. // numbers (either a single int, or an array of ints)
  622. //
  623. static ttn_t indretti_ttn[] = 
  624. {{ TWEAK_OFF     , "Off"            }
  625. ,{ TWEAK_COURSE  , "Course"         }
  626. ,{ TWEAK_SEGMENTS, "Segment"        }
  627. ,{             0 , "CornerSpeed"    }
  628. ,{             1 , "SteerGain"      }
  629. ,{             2 , "SteerDamp"      }
  630. ,{             3 , "SteerBias"      }
  631. ,{             4 , "ExtraSpace"     }
  632. ,{             5 , "CornerSetup"    }
  633. ,{             6 , "BrakeFactor"    }
  634. ,{             7 , "AccelFactor"    }
  635. ,{             8 , "STEFactor"      }
  636. ,{             9 , "STEFactor2"     }
  637. ,{            -1 ,  NULL            }
  638. };
  639.  
  640.  
  641. //
  642. // The config file template for indretti.tsi (Track Setup Info)
  643. // 
  644. static CONFIG_TEMPLATE indretti_config[] =
  645. {{ "CourseRadii"   ,MAXSEG,sizeof(double),0,"%lf" , Radii         }
  646. ,{ "CourseLengths" ,MAXSEG,sizeof(double),0,"%lf" , Lengths       }
  647. ,{ "SegmentList"   ,MAXSEG,   sizeof(int),0,"%d"  , Segments      }
  648. ,{ "ParameterList" , NPARM,   sizeof(int),0,"TN"  , Parameters    }
  649. ,{ "CornerSpeed"   ,MAXSEG,sizeof(double),0,"%lf" , aCORNER_FACT  }
  650. ,{ "SteerGain"     ,MAXSEG,sizeof(double),0,"%lf" , aSTEER_GAIN   }
  651. ,{ "SteerDamp"     ,MAXSEG,sizeof(double),0,"%lf" , aSTEER_DAMP   }
  652. ,{ "SteerBias"     ,MAXSEG,sizeof(double),0,"%lf" , aSTEER_BIAS   }
  653. ,{ "ExtraSpace"    ,MAXSEG,sizeof(double),0,"%lf" , aEXTRA_SPACE  }
  654. ,{ "CornerSetup"   ,MAXSEG,sizeof(double),0,"%lf" , aCORNER_SETUP }
  655. ,{ "BrakeFactor"   ,MAXSEG,sizeof(double),0,"%lf" , aBRAKE_FACT   }
  656. ,{ "AccelFactor"   ,MAXSEG,sizeof(double),0,"%lf" , aACCEL_FACT   }
  657. ,{ "STEFactor"     ,MAXSEG,sizeof(double),0,"%lf" , aSTE_FACT     }
  658. ,{ "STEFactor2"    ,MAXSEG,sizeof(double),0,"%lf" , aSTE_FACT2    }
  659. ,{ "TweakMode"     ,     1,   sizeof(int),0,"TN"  ,&TweakMode     }
  660. ,{ "TweakNLaps"    ,     1,             0,0,"%d"  ,&TweakNLaps    }
  661. ,{ "TweakSStep"    ,     1,             0,0,"%lf" ,&TweakSStep    }
  662. ,{ "TweakEStep"    ,     1,             0,0,"%lf" ,&TweakEStep    }
  663. ,{ "CourseNSeg"    ,     1,             0,0,"%d"  ,&cNSEG         }
  664. ,{ "CourseWidth"   ,     1,             0,0,"%lf" ,&cwidth        }
  665. ,{ NULL        , -1 }
  666. };
  667.  
  668.  
  669.  
  670. //
  671. // MI 4-95
  672. // Take the current configuration variables and write them into a
  673. // .twk file.  This means updates to the .tsi file must be done
  674. // manually.  For now, I prefer things this way.
  675. //
  676. void WriteIndrettiConfig( void )
  677. {    int  i,j;
  678.     FILE *fp;
  679.   double *flist;
  680.  
  681.   fp = fopen( "indretti.twk" , "w" );
  682.   if ( fp == NULL )
  683.     return;
  684.   
  685.   // Output the control factor matrix
  686.   i = 0;
  687.   while (( factors[i] != NULL ) && ( i < NPARM ))
  688.     { fprintf( fp , "//TSI:%s =" , number_to_text( i , indretti_ttn ) );
  689.       flist = factors[i];
  690.       for ( j = 0 ; j < NSEG ; j++ )
  691.         fprintf( fp , " %15.9lf" , flist[j] );
  692.       fprintf( fp , "\n" );
  693.       i++;
  694.     }
  695.  
  696.   // Other stuff might follow, but this gets the job done
  697.  
  698.   fclose( fp );
  699. }  
  700.         
  701.  
  702. //
  703. // Tweaking routines.  MI 3-95  Just dumping all the control factors into 
  704. // this routine and letting it run forever will NOT get you the fastest setup
  705. // for your driver, but it can help reduce the work in finding a good setup.
  706. //
  707.  
  708. // State variables
  709. #define TWK_START   1
  710. #define TWK_SCAN    2
  711.  
  712.  
  713. //
  714. // MI 3-95
  715. // tweak() should be called at the end of each lap, and passed a time
  716. // for that lap.  You probably want to run solo, or if you are working
  717. // on passing algorithms, you might want to run with traffic.
  718. // My tweak caller only works while running solo.
  719. //      
  720. void tweak( double lap_time )
  721. {
  722.   static    int state       = TWK_START;
  723.   static    int lap_count   = 0;
  724.   static    int wp          = 0; // Parameter that is currently being worked on
  725.   static    int ws          = 0; // Segment that is currently being worked on 
  726.   static double step        ;
  727.   static double start_time  ;
  728.   static double start_value ;
  729.   static double last_time   = 0.0;
  730.   static double this_time   = 0.0;
  731.   static double this_value  = 0.0;
  732.   static double very_best   = 999999.0;
  733.   static double best_time   = 999999.0;
  734.   static double best_value  ;
  735.   static double *flist;
  736.   static   char string[80];
  737.   static    int i;
  738.   static   FILE *fp;
  739.   static    int improved  = 0;
  740.   static   long laps_done = 0;
  741.  
  742.   laps_done++;
  743.  
  744.   if (( TweakMode != TWEAK_COURSE   ) &&
  745.       ( TweakMode != TWEAK_SEGMENTS ))
  746.     return;
  747.  
  748.   this_time += lap_time;
  749.   if ( ++lap_count < TweakNLaps )
  750.     return;
  751.  
  752.   if ( TweakMode == TWEAK_COURSE )
  753.     { Segments[0] = 0;
  754.       ws = 0;
  755.     }
  756.   flist = factors[Parameters[wp]];
  757.   this_value = flist[Segments[ws]];
  758.  
  759.   switch ( state )
  760.     { case TWK_START:
  761.         flist = factors[Parameters[wp]];
  762.         start_value  = flist[Segments[ws]];
  763.         start_time   = this_time;
  764.         best_time    = this_time;
  765.         best_value   = start_value;
  766.         step         = TweakSStep;
  767.         if ( TweakMode == TWEAK_SEGMENTS )
  768.           { flist = factors[Parameters[wp]];
  769.             flist[Segments[ws]] *= ( 1.0 + step );
  770.           }
  771.         if ( TweakMode == TWEAK_COURSE )
  772.           for ( i = 0 ; i < NSEG ; i++ )
  773.             { flist = factors[Parameters[wp]];
  774.               flist[i] *= ( 1.0 + step );
  775.             }
  776.         state = TWK_SCAN;
  777.         break;
  778.  
  779.       case TWK_SCAN:
  780.         if ( this_time <= last_time )
  781.           { // The change worked, keep going with it
  782.             if ( this_time < best_time )
  783.               { best_time    = this_time;
  784.                 flist = factors[Parameters[wp]];
  785.                 best_value   = flist[Segments[ws]];
  786.                 improved     = 1;
  787.  
  788.                 if ( best_time < very_best )
  789.                   { very_best = best_time;
  790.                     WriteIndrettiConfig();
  791.                   }
  792.               }
  793.             if ( TweakMode == TWEAK_SEGMENTS )
  794.               { flist = factors[Parameters[wp]];
  795.                 flist[Segments[ws]] *= ( 1.0 + step );
  796.               }
  797.             if ( TweakMode == TWEAK_COURSE )
  798.               for ( i = 0 ; i < NSEG ; i++ )
  799.                 { flist = factors[Parameters[wp]];
  800.                   flist[i] *= ( 1.0 + step );
  801.                 }
  802.           }
  803.          else
  804.           { // Improvement has run-out , back up & take smaller steps
  805.             step *= -0.5;
  806.             if ( TweakMode == TWEAK_SEGMENTS )
  807.               { flist = factors[Parameters[wp]];
  808.                 flist[Segments[ws]] *= ( 1.0 + step );
  809.               }
  810.             if ( TweakMode == TWEAK_COURSE )
  811.               for ( i = 0 ; i < NSEG ; i++ )
  812.                 { flist = factors[Parameters[wp]];
  813.                   flist[i] *= ( 1.0 + step );
  814.                 }
  815.  
  816.             if (( step < TweakEStep ) && ( -step < TweakEStep ))
  817.               { // Done tweaking this one, go to the next
  818.                 if ( TweakMode == TWEAK_SEGMENTS )
  819.                   { flist = factors[Parameters[wp]];
  820.                     flist[Segments[ws]] = best_value;
  821.                   }
  822.                 if ( TweakMode == TWEAK_COURSE )
  823.                   for ( i = 0 ; i < NSEG ; i++ )
  824.                     { flist = factors[Parameters[wp]];
  825.                       flist[i] = best_value;
  826.                     }
  827.  
  828.  
  829.                 if ( Parameters[ ++wp ] < 0  )
  830.                   { wp = 0;
  831.                     if ( TweakMode == TWEAK_SEGMENTS )
  832.                       { if ( Segments[ ++ws ] < 0 )
  833.                           ws = 0;
  834.                       }
  835.                      else
  836.                       { if ( improved )
  837.                           improved = 0;
  838.                          else
  839.                           { printf( "No improvement found, quitting.\n" );
  840.                             exit( 0 );
  841.                           }
  842.                       } 
  843.                   }
  844.                 state = TWK_START;
  845.               }
  846.              else
  847.               state = TWK_SCAN;
  848.           }
  849.         break;
  850.  
  851.       default:
  852.         state = TWK_START;
  853.         break;
  854.     }
  855.  
  856.  
  857. // System dependant code
  858. #ifdef WATCOM
  859.   _settextposition( 1 , 1 );
  860.   sprintf( string , "Start Time %7.2lf Start Value %12.9lf\n", start_time/TweakNLaps, start_value ); _outtext( string );
  861.   sprintf( string , " Best Time %7.2lf  Best Value %12.9lf\n",  best_time/TweakNLaps,  best_value ); _outtext( string );
  862.   sprintf( string , " Last Time %7.2lf  Last Value %12.9lf\n",  this_time/TweakNLaps,  this_value ); _outtext( string );
  863.   sprintf( string , " Step Size %7.4lf Var %s Seg %d Laps %ld  \n", step, number_to_text( Parameters[wp] , indretti_ttn ), Segments[ws] , laps_done ); _outtext( string );
  864. #endif
  865.  
  866.   lap_count = 0;         
  867.   last_time = this_time; // For future reference                                           
  868.   this_time = 0.0;       // Reset accumulator
  869. }
  870.  
  871.  
  872. //
  873. // MI 4-95
  874. // Similar - are the two numbers within 2% of each-other?
  875. // I use this comparison because floating point numbers
  876. // have been known to vary slightly.  Also, minor tuning to
  877. // a track should not require the driver to re-learn it.
  878. //
  879. static int similar( double a , double b )
  880. { double d;
  881.  
  882.   if ( a == b )
  883.     return 1;
  884.  
  885.   if (( a == 0.0 ) || ( b == 0.0 ))
  886.     return 0;
  887.  
  888.   d = (a-b)/a;
  889.   if (( d > -0.02 ) && ( d < 0.02 ))
  890.     return 1;
  891.  
  892.   return 0;
  893. }
  894.  
  895.  
  896. //
  897. // MI 4-95
  898. // Track segment compare function.
  899. // Compare the radius, length and width passed to the corresponding
  900. // segment of the current track.  If they agree within +-2%, return
  901. // a 1 (match) otherwise return a 0 (no match)
  902. //
  903. static int ts_compare( int i , double r , double l , double w )
  904.   double rad = trackout[i].radius - trackin[i].radius;
  905.   if ( rad < 0.0 )
  906.     rad = -rad;
  907.  
  908.   if ( similar( r , trackout[i].radius ) && 
  909.        similar( l , trackout[i].length ) )
  910.     { if ( r != 0 )
  911.         { if ( similar( w , rad ) )
  912.             return 1;
  913.            else
  914.             return 0;
  915.         }
  916.        else
  917.         return 1;
  918.     }
  919.   return 0;
  920. }
  921.  
  922.  
  923. //
  924. // MI 4-95
  925. // Compare the currently read track to the one in use.
  926. //
  927. int MatchTrack( void )
  928. { int match, i;
  929.  
  930.   if ( cNSEG != NSEG )
  931.     return 0;
  932.  
  933.   match = 1;
  934.   i = 0;
  935.   while ( i < NSEG )
  936.     { if ( !ts_compare( i , Radii[i] , Lengths[i] , cwidth ) )
  937.         match = 0;
  938.       i++;
  939.     }
  940.  
  941.   return match;
  942. }
  943.  
  944.  
  945. //
  946. // MI 4-95
  947. // Clear out the variables to be read from the config file
  948. // so they don't contain "residual" values from previous tracks
  949. //
  950. static void ClearVars( void )
  951. {    int  i,j;
  952.   double *flist;
  953.  
  954.   TweakMode = TWEAK_OFF;
  955.  
  956.   for ( i = 0 ; i < MAXSEG ; i++ )
  957.     Segments[i] = -1;
  958.   for ( i = 0 ; i <  NPARM ; i++ )
  959.     Parameters[i] = -1;
  960.  
  961.   for ( i = 0 ; i < NSEG ; i++ )
  962.     { j = 0;
  963.       while ( def_fact[j] != NULL )
  964.         { flist = factors[j];
  965.           flist[i] = *(def_fact[j]);
  966.           j++;
  967. }   }   }
  968.  
  969.  
  970. // 
  971. // MI 4-95
  972. // If there is a "indretti.cpp" file, try to match the current
  973. // track to one found in the file and set the driver's parameters 
  974. // accordingly.
  975. //
  976. static int read_track_file( void )
  977. { FILE *fp;
  978.    int  done  = 0;
  979.    int  match = 0;
  980.  
  981.   fp = fopen( "indretti.cpp" , "r" );
  982.   if ( fp == NULL )
  983.     return 0;  // Could not open file, so give up and use default values
  984.  
  985.   while ( !done )
  986.     { ClearVars();
  987.       if ( !ReadConfigFilePiece( fp, indretti_config, indretti_ttn ) ) 
  988.         done = 1;
  989.       if ( feof( fp ) ) 
  990.         done = 1;
  991.       if ( MatchTrack() )
  992.         { done  = 1;
  993.           match = 1;
  994.         }
  995.     }    
  996.   fclose( fp );
  997.  
  998.   return match;
  999. }
  1000.  
  1001.  
  1002. //
  1003. // MI 4-95
  1004. // Allocate memory for all these arrays.
  1005. // Read the .tsi file to see if we have a match, if so, use it.
  1006. // If not, paste over all the values with the default values.
  1007. //
  1008. void ConfigureIndretti( void )
  1009. { Radii          = new double[MAXSEG]; 
  1010.   Lengths        = new double[MAXSEG]; 
  1011.   Segments       = new    int[MAXSEG]; 
  1012.   Parameters     = new    int[ NPARM]; 
  1013.  
  1014.   indretti_config[0].params = (void *)Radii     ; 
  1015.   indretti_config[1].params = (void *)Lengths   ; 
  1016.   indretti_config[2].params = (void *)Segments  ; 
  1017.   indretti_config[3].params = (void *)Parameters; 
  1018.  
  1019.   aCORNER_FACT   = factors[0] = new double[MAXSEG];
  1020.   aSTEER_GAIN    = factors[1] = new double[MAXSEG];
  1021.   aSTEER_DAMP    = factors[2] = new double[MAXSEG];
  1022.   aSTEER_BIAS    = factors[3] = new double[MAXSEG];
  1023.   aEXTRA_SPACE   = factors[4] = new double[MAXSEG];
  1024.   aCORNER_SETUP  = factors[5] = new double[MAXSEG];
  1025.   aBRAKE_FACT    = factors[6] = new double[MAXSEG];
  1026.   aACCEL_FACT    = factors[7] = new double[MAXSEG];
  1027.   aSTE_FACT      = factors[8] = new double[MAXSEG];
  1028.   aSTE_FACT2     = factors[9] = new double[MAXSEG];
  1029.  
  1030.   indretti_config[ 4].params = (void *)aCORNER_FACT ; 
  1031.   indretti_config[ 5].params = (void *)aSTEER_GAIN  ; 
  1032.   indretti_config[ 6].params = (void *)aSTEER_DAMP  ; 
  1033.   indretti_config[ 7].params = (void *)aSTEER_BIAS  ; 
  1034.   indretti_config[ 8].params = (void *)aEXTRA_SPACE ; 
  1035.   indretti_config[ 9].params = (void *)aCORNER_SETUP; 
  1036.   indretti_config[10].params = (void *)aBRAKE_FACT  ; 
  1037.   indretti_config[11].params = (void *)aACCEL_FACT  ; 
  1038.   indretti_config[12].params = (void *)aSTE_FACT    ; 
  1039.   indretti_config[13].params = (void *)aSTE_FACT2   ; 
  1040.  
  1041.   if ( !read_track_file() )
  1042.     ClearVars(); // Couldn't find this track in the file, so use the default values
  1043.  
  1044. }
  1045.  
  1046. //
  1047. // Sometimes it is helpful to see the current "state" on-screen
  1048. // Calling dump_indretti will display several variables
  1049. //
  1050. static int dump = 0;
  1051. void dump_indretti( void )
  1052. { dump = 1;
  1053. }
  1054.  
  1055.  
  1056.  
  1057. //////////////////////
  1058. // Driving Routines //
  1059. //////////////////////
  1060.  
  1061.  
  1062.  
  1063. //
  1064. // Given a radius (in feet), compute the desired speed (in feet per second)
  1065. // MI 3-95
  1066. //
  1067. double desired_speed( double rad )
  1068. { double val;
  1069.  
  1070.   if ( rad < 0.0 )
  1071.     rad = -rad;
  1072.  
  1073.   if (( rad > 10000.0 ) || ( rad == 0.0 ))
  1074.     return 500.0;
  1075.  
  1076.   if ( rad < 25.0 )
  1077.     rad = 25.0;
  1078.  
  1079.   val = sqrt( rad ) * aCORNER_FACT[seg]; 
  1080.   if ( val > 500.0 ) val = 500.0;
  1081.  
  1082.   return val;
  1083. }
  1084.  
  1085.  
  1086. //
  1087. // Given two desired speeds, compute the time required to go from s1 to s2
  1088. // MI 3-95
  1089. //
  1090. double exit_time( double s1, double s2 )
  1091. { double diffsq = ( s1 - s2 ) * ( s1 - s2 );
  1092.  
  1093.   if ( s1 > s2 )
  1094.     return diffsq * aBRAKE_FACT[seg]; 
  1095.   return diffsq * aACCEL_FACT[seg];
  1096. }
  1097.  
  1098.  
  1099. //
  1100. // Given a radius, distance, and width, determine if the driver cannot
  1101. //   "see the end" of this turn and therefore must hold off on 
  1102. //   acceleration/braking for the next segment.
  1103. // MI 3-95
  1104. //
  1105. int cannot_see_end( double r ,double d , double w )
  1106.   if ( r < 0 )
  1107.     r = -r;
  1108.   
  1109.   // Straight or nearly straight
  1110.   if (( r > 10000.0 ) || ( r == 0.0 ))    return 0;
  1111.                                          
  1112.   // More than x degrees to go
  1113.   if ( d / r > aSTE_FACT2[seg] )                return 1;
  1114.  
  1115.   // Road is too narrow to "see out"
  1116.   if ( aSTE_FACT[seg] * d * d > w * w + 2*r*w ) return 1;
  1117.  
  1118.   return 0;
  1119. }
  1120.  
  1121.  
  1122. /////////////////////////////////////////////////////////////////////
  1123. // The Michael Indretti driver, by Mike Inman 3-95                 //
  1124. //                                                                 //
  1125. // Nothing too fancy here, the real power of this driver is in the //
  1126. // tweaking and track identification routines.                     //
  1127. /////////////////////////////////////////////////////////////////////
  1128.  
  1129. con_vec Indretti(situation& s)
  1130. {
  1131.   const     char name[]    = "Indretti"; // This is the robot driver's name
  1132.   static  double last_to_end = 999999.9; // To watch for crossings into new segments
  1133.   static  double last_rad    = 999999.9; // To watch for crossings into new segments
  1134.   static     int init_flag = 1;          // cleared by first call
  1135.   static     int relax = 1;              // cleared first time through
  1136.          con_vec result;                 // This is what is returned
  1137.           double alpha;                  // Working variable
  1138.           double dest;                   // Destination location on track
  1139.           double tte;                    // Time to end (this segment) 
  1140.           double tv;                     // Target Velocity
  1141.           double bias;                   // Used in steering
  1142.           double length;                 // Linearized length number
  1143.           double to_end;                 // Linearized to_end length
  1144.           double cur_rad;
  1145.             char string[80];  
  1146.  
  1147.   if ( s.starting )
  1148.     { ConfigureIndretti();               // Try to match up the current track to a known one
  1149.       seg = 0;
  1150.       relax = 1;
  1151.     }
  1152.  
  1153.   if (init_flag)                         // first time through, copy name
  1154.     { my_name_is(name);
  1155.       init_flag = 0;
  1156.       result.alpha = result.vc = 0;
  1157.       return result;
  1158.     }
  1159.  
  1160.   cur_rad = s.cur_rad;
  1161.   if ( cur_rad < 0.0 ) 
  1162.     cur_rad = -cur_rad;
  1163.  
  1164.   // Straighten the curves
  1165.   if ( s.cur_rad == 0.0 )
  1166.     { length = s.cur_len;
  1167.       to_end = s.to_end;
  1168.     }
  1169.    else
  1170.     { length = s.cur_len * cur_rad;   
  1171.       to_end = s.to_end * cur_rad;
  1172.     }
  1173.  
  1174.   // Keep track of the current segment
  1175.   if ( relax )
  1176.     relax = 0;  // Used to get jumpy at the start of races & skip one
  1177.    else
  1178.     { if (( to_end > last_to_end ) && ( s.cur_rad != last_rad ))
  1179.         if ( ++seg >= NSEG )
  1180.           seg = 0;
  1181.     }
  1182.  
  1183.   last_to_end = to_end;
  1184.   last_rad    = s.cur_rad;
  1185.  
  1186.   // Distance to destination
  1187.   if ( to_end > length/2 )
  1188.     { // In the 1st half of the segment
  1189.       if ( s.cur_rad == 0 )
  1190.         { if ( s.nex_rad > 0 )
  1191.             dest = (s.to_lft + s.to_rgt) * (1.0 - aCORNER_SETUP[seg]);
  1192.            else
  1193.             dest = (s.to_lft + s.to_rgt - CARWID ) * aCORNER_SETUP[seg];
  1194.         }
  1195.        else
  1196.         { if ( s.cur_rad > 0 )
  1197.             dest = aEXTRA_SPACE[seg];
  1198.            else
  1199.             dest = s.to_lft + s.to_rgt - aEXTRA_SPACE[seg];
  1200.         }
  1201.     }
  1202.    else
  1203.     { // In the second half of the segment
  1204.       if ( cannot_see_end( s.cur_rad , to_end , s.to_lft + s.to_rgt ) )
  1205.         { if ( s.cur_rad > 0 )
  1206.             dest = aEXTRA_SPACE[seg];
  1207.            else
  1208.             dest = s.to_lft + s.to_rgt - aEXTRA_SPACE[seg];
  1209.         }
  1210.        else
  1211.         { if ( s.nex_rad == 0 )
  1212.             { if ( s.after_rad > 0 )
  1213.                 dest = (s.to_lft + s.to_rgt) * (1.0 - aCORNER_SETUP[seg]);
  1214.                else
  1215.                 dest = (s.to_lft + s.to_rgt - CARWID ) * aCORNER_SETUP[seg];
  1216.             }
  1217.            else
  1218.             { if (( s.cur_rad > 0 ) && ( s.nex_rad > 0 ))
  1219.                 dest = aEXTRA_SPACE[seg];
  1220.               else if (( s.cur_rad < 0 ) && ( s.nex_rad < 0 ))
  1221.                 dest = s.to_lft + s.to_rgt - aEXTRA_SPACE[seg];
  1222.               else
  1223.                 { if ( s.nex_rad > 0 )
  1224.                     dest = (s.to_lft + s.to_rgt) * (1.0 - aCORNER_SETUP[seg]);
  1225.                    else
  1226.                     dest = (s.to_lft + s.to_rgt - CARWID ) * aCORNER_SETUP[seg];
  1227.                 }
  1228.             }
  1229.         }
  1230.     }
  1231.  
  1232.   // Time to end
  1233.   if ( s.v > 1.0 )
  1234.     tte  = to_end / s.v; 
  1235.    else
  1236.     tte  = 60.0;  // Override setting incase of slow speeds
  1237.  
  1238.  
  1239.   // Desired driving speeds:
  1240.   //   If the time to the end of the segment is greater than exit_time()
  1241.   //   (which is determined by the relative desired_speed()s for the segments)
  1242.   //   hold speed to the desired speed for this segment, otherwise, target
  1243.   //   speed is the target speed for the next segment, unless in the middle
  1244.   //   of a corner where the driver "cannot see the end", then hold to
  1245.   //   the desired speed for this segment.
  1246.  
  1247.   if (( tte > exit_time( s.v , desired_speed( s.nex_rad ) ) ) ||
  1248.       cannot_see_end( s.cur_rad , to_end , s.to_lft + s.to_rgt ) )
  1249.     tv = desired_speed( s.cur_rad );
  1250.    else
  1251.     tv = desired_speed( s.nex_rad );
  1252.  
  1253.   // Steering:
  1254.  
  1255.   if (s.cur_rad == 0.0)     // calculate a bias for alpha in a turn:
  1256.     bias = 0.0;
  1257.    else 
  1258.     { if (s.cur_rad > 0.0)
  1259.         { if ( s.to_lft > 1.0 )
  1260.             bias =  aSTEER_BIAS[seg] / desired_speed( s.cur_rad );
  1261.            else
  1262.             bias =  0.0;
  1263.         }
  1264.        else
  1265.         { if ( s.to_rgt > CARWID - 1.0 )
  1266.             bias = -aSTEER_BIAS[seg] / desired_speed( s.cur_rad );
  1267.            else
  1268.             bias = 0.0;
  1269.     }   }
  1270.  
  1271.   alpha  = bias + aSTEER_GAIN[seg] * ( s.to_lft - dest ) / (s.to_lft + s.to_rgt);
  1272.   alpha -= aSTEER_DAMP[seg] * s.vn / s.v;  // This is damping, to prevent oscillation
  1273.  
  1274.   result.vc    = tv;   
  1275.   result.alpha = alpha;
  1276.  
  1277.  
  1278. // This is system dependant code
  1279. #ifdef WATCOM
  1280.   if ( dump )
  1281.     { _settextposition( 1 , 1 );
  1282.       sprintf( string , "  alpha %7.4lf,      vc %7.2lf\n", alpha    , tv );        _outtext( string );
  1283.       sprintf( string , "      v %7.2lf,      vn %7.2lf\n", s.v      , s.vn );      _outtext( string );
  1284.       sprintf( string , " to_lft %7.2lf,    dest %7.2lf\n", s.to_lft , dest );  _outtext( string );
  1285.       sprintf( string , "cur_rad %7.2lf, cur_len %7.2lf\n", s.cur_rad, length ); _outtext( string );
  1286.       sprintf( string , " cur_ds %7.2lf,  nex_ds %7.2lf\n", desired_speed( s.cur_rad ) , desired_speed( s.nex_rad ) ); _outtext( string );
  1287.       sprintf( string , "    tte %7.2lf, exit_tm %7.2lf\n", tte, exit_time( s.v  , desired_speed( s.nex_rad )) ); _outtext( string );
  1288.       sprintf( string , "   cnse %1d seg %ld to_end %7.2lf\n", cannot_see_end( s.cur_rad , to_end , s.to_lft + s.to_rgt ), seg, to_end ); _outtext( string );
  1289.              
  1290.       _settextposition( 15 , 1 );
  1291.       sprintf( string , "  bias %7.4lf    gain %7.4lf\n", bias, aSTEER_GAIN[seg] );        _outtext( string );
  1292.       sprintf( string , "  dest %7.4lf to_left %7.4lf to_right %7.4lf cs %7.4lf\n", dest, s.to_lft, s.to_rgt, aCORNER_SETUP[seg] );  _outtext( string );
  1293.       sprintf( string , "  s.vn %7.4lf     s.v %7.4lf\n", s.vn, s.v  );        _outtext( string );
  1294.     }
  1295. #endif                                                    
  1296.  
  1297.  
  1298.   return result;
  1299. }
  1300.